#include <iostream>
#include "socket.h"
#include <sys/time.h>
using namespace std;

const string version = "1.1.2";
static string ip;
static int port;
static int maxPacketNum;
static int maxConnectNum = 1;
static string text;

void Error(const string &str){
	cout<<str<<endl;
}

void sayHelp(){
	cout<<"pt : version "<<version<<endl;
	cout<<"usage pt [-ipmnt]"<<endl<<endl;
	cout<<" -i \t\tthe dest host"<<endl;
	cout<<" -p \t\tthe dest port"<<endl;
	cout<<" -n \t\tneed send packet num"<<endl;
	cout<<" -m \t\thow many process will send send packet "<<endl;
	cout<<" -t \t\tthe text of sending"<<endl;
}

struct timeval getTime(){
	struct timeval tv;
	struct timezone tz;
	int ret = gettimeofday(&tv, &tz);	
	return tv;
}

void *sendPacket(void *){

	int fd = CSocket::create();
	if( fd < 0 ){
		Error("create socket error");
		return NULL;
	}

	int ret = CSocket::connect(fd, ip, port);
	if( ret < 0 ){
		Error("connect socket error");
		return NULL;
	}
	unsigned send_len;
	for(int i=0; i<maxPacketNum; i++ ){
		CSocket::send(fd, text.c_str(), text.size(), send_len);
	}
	CSocket::close(fd);
	return NULL;
}

int main(int argc, char** argv){

	int c;
	if( argc <= 1 ){
		sayHelp();	
		return 0;
	}
	while((c=getopt(argc, argv, "i:p:n:m:t:h")) != -1){
		switch(c){
			case 'i':
				ip = optarg;
				if(ip == ""){
					goto HELP;
				}
				break;
			case 'p':
			{
				int _p = atoi(optarg);
				if( _p <= 0 ){
					Error("port error");
					goto HELP;
				}
				port = _p;
				break;
			}
			case 'n':
			{
				int _n = atoi(optarg);
				if( _n <= 0){
					Error("maxNum error");
					goto HELP;
				}
				maxPacketNum= _n;
				break;
			}
			case 'm':
			{
				int _m = atoi(optarg);
				if( _m <= 0){
					Error("connect error");
					goto HELP;
				}
				maxConnectNum= _m;
				break;
			}
			case 't':
HELP:
				text = optarg;
				break;
			case 'h':
			default:
				sayHelp();	
				return 0;

		}
	}

	cout<<"ip:"<<ip<<endl;
	cout<<"port:"<<port<<endl;
	cout<<"process:"<<maxConnectNum<<endl;
	cout<<"packet:"<<maxPacketNum<<endl;

	struct timeval begin = getTime();
	if( maxConnectNum > 1 ){
		pthread_t *pth_id = new pthread_t[maxConnectNum];
		for(int i=0; i<maxConnectNum; i++){
			pthread_create(&pth_id[i], NULL, sendPacket, NULL);
		}
		for(int i=0; i<maxConnectNum; i++){
			pthread_join(pth_id[i], NULL);
		}
	}else if( maxConnectNum == 1 ){
		sendPacket(NULL);	
	}
	struct timeval end = getTime();
	cout<<end.tv_sec - begin.tv_sec<<" s ";
	cout<<end.tv_usec - begin.tv_usec<<endl;
	return 0;


}
